package net.bingosoft.common.swato;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.bingosoft.common.BeanHelper;
import net.bingosoft.common.ObjectRegistry;
import net.bingosoft.common.resource.ResourceManager;
import net.bingosoft.common.util.ClassUtil;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 2008-1-15 上午09:19:40
 * Author:yangdongyu(yangdy@bingosoft.net)
 * ReadMe:
 * ChangeLog:
 */
public class JSONServlet extends HttpServlet {
	
	private static final long serialVersionUID = 1L;

	private static Log log = LogFactory.getLog(JSONServlet.class);

	private static final String CONTEXT_CLASS_KEY = "CONTEXT_CLASS";

	private static final String CONTEXT_FILE_KEY = "CONTEXT_FILE";

	private static ServiceContext m_context;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		String fileName = config.getInitParameter(CONTEXT_FILE_KEY);
		String configClassName = config.getInitParameter(CONTEXT_CLASS_KEY);
		if(StringUtils.isEmpty(fileName) || StringUtils.isEmpty(configClassName)){
			m_context = new ServiceContext(){
				public Object getBean(String id) {
					Object targetBean = null;
					if(ObjectRegistry.containsBean(id)){
						targetBean = ObjectRegistry.getBean(id);
					}else{
						targetBean = ClassUtil.newInstance(id);
					}
					return targetBean; 
				}
				public void setConfigFile(String filename) {}
			};
			return;
		}
		try {
			m_context = (ServiceContext) Class.forName(configClassName).newInstance();
			m_context.setConfigFile(fileName);
		} catch (InstantiationException e) {
			log.error(e);
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			log.error(e);
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			log.error(e);
			e.printStackTrace();
		}
	}

	/*
	 * MethodName Params NOT NULL NOT NULL Call the method(Method Name) of the
	 * Object(id) with parameters NULL Call the method(Method Name) of the
	 * Object(id) without parameters NULL NOT NULL Set the Object(id)'s
	 * properties NULL Get the Object(id)'s properties
	 * 
	 * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String requestPath = req.getRequestURI();
		if(requestPath.contains("/swato/")){
			String fileName = requestPath.split("/swato/")[1];
			processReadJSFile(req, resp,fileName);
		}else{
			processService(req, resp);
		}
		
		
		
	}
	
	/**
	 * 处理js文件的读取
	 * @param req
	 * @param resp
	 * @throws IOException
	 */
	private void processReadJSFile(HttpServletRequest req, HttpServletResponse resp,String fileName) throws IOException{
		ResourceManager.WriteContent2HTML(req, resp, JSONServlet.class, fileName);
	}
	
	/**
	 * 处理具体的服务
	 * @param req
	 * @param resp
	 * @throws IOException
	 */
	private void processService(HttpServletRequest req, HttpServletResponse resp) throws IOException{
		JSONRequest jsonReq = new JSONRequest(req);
		JSONResponse jsonResp = new JSONResponse(resp);

		try {
			Object result = null;
			String serviceId = req.getParameter("serviceId");
			if(serviceId == null){
				String pathInfo = req.getPathInfo();
				if(pathInfo != null && pathInfo.length() > 1)
					serviceId = pathInfo.substring(1);
			}
			if (serviceId != null && serviceId.length() > 1) {
				Object target = m_context.getBean(serviceId);
				SwatoInvoker invoker = new SwatoInvoker();
				if (!BeanHelper.isNull(jsonReq.getMethodName())) {
					log.info("deal with service:" + serviceId + " method: " + jsonReq.getMethodName());
					result = invoker.invoke(jsonReq,resp,target);
				}
			}
			jsonResp.setResult(result);
			if (result != null) {
				jsonResp.setHashCode(String.valueOf(result.hashCode()));
			}

		} catch (InvocationTargetException e) {
			log.error(e);
			jsonResp.setError(e.getTargetException() != null ? e.getTargetException():e);
		} catch (Exception e) {
			jsonResp.setError(e);
			log.error(e);
		}
		jsonResp.flush();
	}
}
